04. 常用内置函数

本章概要

  • 学习材料:证券代码、收益率、估值与缺失字符串列表。
  • 本章任务:用 len/sorted/map/filter/zip 完成 lst-comprehensive-analysis 的配对、筛选和排名。
  • 完成后你将得到:原始长度、清洗后列表、排序键与证券排名表。
  • 自我检查:核对配对长度和排序方向;长度错位或转换失败时先检查原因。
  • 拓展练习:把同一函数方法应用到另一组长三角公司。

本章导览:Python 内置函数

Python 的设计哲学之一是 ‘Batteries Included’(自带电池):

  • 内置函数无需导入任何模块即可直接使用
  • 在金融数据分析中可显著提高代码简洁性和执行效率
  • 本章将系统介绍最常用的内置函数及其商业数据分析应用

本章函数概览

函数类别 核心函数 典型应用场景
序列处理 len(), enumerate(), sum() 数据完整性检查、排名报告
极值函数 max(), min() 识别最佳/最差表现
排序函数 sorted() 数值排序、相对假设阈值分组

本章函数概览:清洗与批处理

函数类别 核心函数 典型应用场景
类型转换 int(), float(), str() 数据清洗、格式化
舍入函数 round() 金融报表精度控制
函数式工具 map(), filter(), zip() 批量计算、条件筛选

len():获取序列长度

len() 函数返回对象的长度或项目个数,适用于字符串、列表、元组、字典等。

  • 时间复杂度:列表、元组、字符串、字典均为 O(1)
  • 金融应用:检查数据完整性
Listing 1: len函数获取序列长度
# 教学示例数据:公司名称仅用于演示序列长度,不构成2018年排名依据
stock = ['中信证券', '国泰君安', '海通证券', '华泰证券', '广发证券',
         '招商证券', '申万宏源', '国信证券', '中信建投', '中国银河']

# len()函数返回列表的元素个数
num_companies = len(stock)
print(f'证券公司数量: {num_companies}')
证券公司数量: 10

len() 应用:数据完整性检查

Listing 2
# 检查数据是否完整
stock = ['中信证券', '国泰君安', '海通证券', '华泰证券', '广发证券',
         '招商证券', '申万宏源', '国信证券', '中信建投', '中国银河']

expected_count = 10  # 期望有10家公司

if len(stock) == expected_count:
    print('数据完整')
else:
    print(f'数据缺失, 期望{expected_count}家, 实际{len(stock)}家')
数据完整

核心要点:在分析数据前,先用 len() 验证数据量是否符合预期。

enumerate():枚举索引和值

enumerate() 在遍历序列时同时返回索引和值,常用于生成带序号的报告。

  • 语法enumerate(iterable, start=0)
  • start 参数指定起始序号(默认从 0 开始)
Listing 3: enumerate函数生成排名报告
展开实现代码
stock = ['中信证券', '国泰君安', '海通证券', '华泰证券', '广发证券',
         '招商证券', '申万宏源', '国信证券', '中信建投', '中国银河']

# start=1 表示排名从1开始
print('2018年净利润排名前5位的证券公司:')
for rank, company in enumerate(stock[:5], start=1):
    print(f'  {rank:2d}. {company}')
2018年净利润排名前5位的证券公司:
   1. 中信证券
   2. 国泰君安
   3. 海通证券
   4. 华泰证券
   5. 广发证券

sum():求和计算

sum() 对可迭代对象进行求和,支持初始值参数。

  • 语法sum(iterable, start=0)
  • 金融应用:计算总利润、平均利润等统计量
Listing 4: sum函数计算净利润总和与平均值
展开实现代码
profit = [98.76, 70.70, 57.71, 51.61, 46.32,
          44.46, 42.48, 34.31, 31.03, 29.32]

# 教学示例数据:数值仅用于演示sum,不构成公司财务事实
# 计算净利润总和
profit_total = sum(profit)
# 计算平均净利润
profit_average = profit_total / len(profit)

print(f'净利润总和: {profit_total:.2f} 亿元')
print(f'平均净利润: {profit_average:.4f} 亿元')
净利润总和: 506.70 亿元
平均净利润: 50.6700 亿元

运行前预测|平台练习:常用内置函数综合应用

  • 输入预测:运行前先写出 stockprofitreturn_Q1price 的业务含义、数据类型或取值范围,并判断哪一个输入最可能改变结果。
  • 结果预测:不展开答案,先预测将得到“2018年净利润排名前10位的证券公司净利润总和(亿元)”相关结果;同时写出方向、数量级或表格/图形结构。
  • 完成要求:能独立说明本任务从输入到“平台练习:常用内置函数综合应用”结果的关键步骤,原样录入平台代码并得到可核对的运行结果。

⭐ 平台练习:常用内置函数综合应用

展开完整代码(投影默认折叠)
# ⚠️ 平台原始代码 - 请原样输入至教学平台(注释除外),平台才会判定答案正确
stock = ["中信证券","国泰君安","海通证券","华泰证券","广发证券","招商证券","申万宏源","国信证券","中信建设","中国银河"]  # 定义列表stock
# 定义列表profit
profit = [98.7643,70.7004,57.7071,51.6089,46.3205,44.4626,42.4781,34.3125,31.0343,29.3174]
# 定义列表return_Q1
return_Q1 = [0.547783,0.315274,0.594318,0.383333,0.275237,0.307463,0.356265,0.617682,1.93341,0.734604]
price = [24.78,20.15,14.03,22.41,16.17,17.52,5.52,13.54,25.55,11.83]  # 定义列表price
#输出列表中元素的个数
print(len(stock))   

#以列表方式输出stock
print(list(enumerate(stock,start=1)))  

#计算10家证券公司的净利润总和
profit_total =sum(profit)       

#计算每家证券公司平均净利润
profit_average =profit_total/len(stock)    

print("2018年净利润排名前10位的证券公司净利润总和(亿元)",profit_total)  # 输出2018年净利润排名前10位的证券公司净利润总和(
print("2018年净利润排名前10位的证券公司净利润平均数(亿元)",round(profit_average,4))  # 输出2018年净利润排名前10位的证券公司净利润平均数
#找出最大涨幅
return_max =max(return_Q1)    
#找出最小涨幅
return_min =min(return_Q1)                       

print("2019年1季度股价的最大涨幅",return_max)  # 输出2019年1季度股价的最大涨幅
print("2019年1季度股价的最小涨幅",return_min)  # 输出2019年1季度股价的最小涨幅
#将股价由小到大排序
price_sorted =sorted(price)                  
print(price_sorted)  # 输出按价格升序排列的证券公司股价列表

任务复盘|平台练习:常用内置函数综合应用

运行后核对:核对 stockprofitreturn_Q1price 是否按预测参与运算,实际输出是否与预测一致;若不一致,先检查类型、单位、索引/字段和运算顺序。

拓展练习:只改变一个关键输入或业务场景,先预测输出如何变化,再运行验证并解释变化原因。

max():找出最大值

max() 返回可迭代对象的最大值,用于识别最佳表现。

Listing 5: max函数识别最佳表现股票
# 教学示例数据:无来源固定数值仅用于演示max,不构成2019Q1市场事实
stock = ['中信证券', '国泰君安', '海通证券', '华泰证券', '广发证券',
         '招商证券', '申万宏源', '国信证券', '中信建投', '中国银河']
return_Q1 = [0.547783, 0.315274, 0.594318, 0.383333, 0.275237,
             0.307463, 0.356265, 0.617682, 1.93341, 0.734604]

# 找出最大涨幅
return_max = max(return_Q1)
best_index = return_Q1.index(return_max)
best_company = stock[best_index]

print(f'最大涨幅: {return_max:.2%}')
print(f'表现最佳: {best_company}')
最大涨幅: 193.34%
表现最佳: 中信建投

min():找出最小值

min() 返回可迭代对象的最小值,用于识别风险资产。

Listing 6: min函数识别最差表现股票
return_Q1 = [0.547783, 0.315274, 0.594318, 0.383333, 0.275237,
             0.307463, 0.356265, 0.617682, 1.93341, 0.734604]

# 找出最小涨幅
return_min = min(return_Q1)
print(f'最小涨幅: {return_min:.2%}')

# 风险预警: 检测是否存在亏损
if return_min < 0:
    print(f'警告: 存在亏损, 最大跌幅 {return_min:.2%}')
else:
    print('所有股票本季度均为正收益')
最小涨幅: 27.52%
所有股票本季度均为正收益

max() / min()key 参数

key 参数可以自定义比较标准,在处理复杂数据结构时非常实用。

Listing 7: 使用key参数自定义排序标准
stocks_info = [
    {'name': '中信证券', 'profit': 98.76, 'pe': 15.2},
    {'name': '国泰君安', 'profit': 70.70, 'pe': 12.8},
    {'name': '海通证券', 'profit': 57.71, 'pe': 18.5}
]

# 按净利润找出最大
most_profitable = max(stocks_info, key=lambda x: x['profit'])
print(f'最盈利: {most_profitable["name"]}')

# 按PE比率找出最小(估值最低)
cheapest = min(stocks_info, key=lambda x: x['pe'])
print(f'最低PE: {cheapest["name"]}')
最盈利: 中信证券
最低PE: 国泰君安

sorted():排序操作

sorted() 返回排序后的新列表,原对象保持不变。

  • 语法sorted(iterable, key=None, reverse=False)
Listing 8: sorted函数对股价进行排序
price = [24.78, 20.15, 14.03, 22.41, 16.17,
         17.52, 5.52, 13.54, 25.55, 11.83]

# 升序排序(默认)
price_sorted = sorted(price)
print(f'股价升序: {price_sorted}')

# 降序排序
price_desc = sorted(price, reverse=True)
print(f'股价降序: {price_desc}')
股价升序: [5.52, 11.83, 13.54, 14.03, 16.17, 17.52, 20.15, 22.41, 24.78, 25.55]
股价降序: [25.55, 24.78, 22.41, 20.15, 17.52, 16.17, 14.03, 13.54, 11.83, 5.52]

sorted() 应用:相对假设阈值分组

Listing 9
price = [24.78, 20.15, 14.03, 22.41, 16.17,
         17.52, 5.52, 13.54, 25.55, 11.83]

# 设置仅供语法演示的假设阈值
assumed_threshold = 18.0

# 列表推导式筛选
above_threshold = [p for p in price if p > assumed_threshold]
below_threshold = [p for p in price if p < assumed_threshold]

print(f'ABOVE_ASSUMED_THRESHOLD数量: {len(above_threshold)}, 数值: {sorted(above_threshold)}')
print(f'BELOW_ASSUMED_THRESHOLD数量: {len(below_threshold)}, 数值: {sorted(below_threshold)}')
ABOVE_ASSUMED_THRESHOLD数量: 4, 数值: [20.15, 22.41, 24.78, 25.55]
BELOW_ASSUMED_THRESHOLD数量: 6, 数值: [5.52, 11.83, 13.54, 14.03, 16.17, 17.52]

18 只是确定性列表分组示例数据,不是估值模型或金融行动阈值;输出只验证 sorted() 与推导式,不进入推荐或执行流程。

sorted().sort() 的区别

特性 sorted() .sort()
返回值 新列表 None(原地修改)
原对象 不变 改变
适用对象 所有可迭代对象 仅列表
Listing 10: sorted与sort的比较
展开实现代码
prices = [24.78, 20.15, 14.03]

# sorted(): 创建新列表, 原列表不变
sorted_prices = sorted(prices)
print(f'原列表: {prices}')
print(f'新列表: {sorted_prices}')

# .sort(): 原地修改
prices_copy = prices.copy()
prices_copy.sort()
print(f'原地修改后: {prices_copy}')
原列表: [24.78, 20.15, 14.03]
新列表: [14.03, 20.15, 24.78]
原地修改后: [14.03, 20.15, 24.78]

类型转换:int(), float(), str()

这些函数在不同数据类型之间进行转换,在数据清洗中极为常用。

Listing 11: 类型转换在金融数据清洗中的应用
# 从CSV读取的数据通常是字符串类型
price_str = '1850.50'
volume_str = '2500000'

# 转换为数值类型后才能进行计算
price = float(price_str)
volume = int(volume_str)

# 计算成交额
turnover = price * volume
print(f'成交额: {turnover:,.0f} 元')
成交额: 4,626,250,000 元

类型转换应用:处理缺失值

Listing 12
# 包含缺失值的原始数据
missing_values = ['', 'N/A', 'None', '1850.50']

for val in missing_values:
    if val not in ['', 'N/A', 'None']:
        price = float(val)
        print(f'有效价格: {price}')
    else:
        print(f'缺失值: "{val}"')
缺失值: ""
缺失值: "N/A"
缺失值: "None"
有效价格: 1850.5

核心要点:先判断数据有效性,再执行类型转换,避免运行时错误。

round():数值舍入

  • 语法round(number, ndigits=None)
  • 注意:Python 3 采用银行家舍入(Round Half to Even)

\[ \large{ \text{round}(2.5) = 2, \quad \text{round}(3.5) = 4 } \]

Listing 13: round函数在金融报表中的应用
展开实现代码
profit = [98.76, 70.70, 57.71, 51.61, 46.32,
          44.46, 42.48, 34.31, 31.03, 29.32]
profit_total = sum(profit)
profit_average = profit_total / len(profit)

print(f'精确值:      {profit_average}')
print(f'保留4位小数: {round(profit_average, 4)}')
print(f'保留2位小数: {round(profit_average, 2)}')
print(f'取整:        {round(profit_average)}')
精确值:      50.67
保留4位小数: 50.67
保留2位小数: 50.67
取整:        51

银行家舍入 vs 常规四舍五入

Listing 14
展开 Decimal 舍入对照代码
# 银行家舍入: 选择最近的偶数
print(f'round(2.5) = {round(2.5)}')  # 输出: 2
print(f'round(3.5) = {round(3.5)}')  # 输出: 4

# 金融场景: 推荐使用 Decimal 模块
from decimal import Decimal, ROUND_HALF_UP

value = Decimal('2.5')
rounded = value.quantize(Decimal('1'), rounding=ROUND_HALF_UP)
print(f'常规四舍五入: {rounded}')  # 输出: 3
round(2.5) = 2
round(3.5) = 4
常规四舍五入: 3

金融建议:涉及资金计算时,使用 Decimal 模块确保精度。

statistics 模块:基本统计量

Python 标准库 statistics 模块提供了丰富的统计函数。

Listing 15: statistics模块的统计函数应用
import statistics

returns = [0.05, 0.03, -0.02, 0.04, 0.06, 0.02, -0.01, 0.07]

mean_val = statistics.mean(returns)
median_val = statistics.median(returns)
stdev_val = statistics.stdev(returns)

print(f'算术平均: {mean_val:.4f}')
print(f'中位数:   {median_val:.4f}')
print(f'标准差:   {stdev_val:.4f}')
print(f'方差:     {statistics.variance(returns):.4f}')
算术平均: 0.0300
中位数:   0.0350
标准差:   0.0321
方差:     0.0010

金融应用:夏普比率计算

夏普比率衡量每承担一单位风险获得的超额收益:

\[ \large{ \text{Sharpe Ratio} = \frac{E(R) - R_f}{\sigma} } \]

Listing 16
import statistics

returns = [0.05, 0.03, -0.02, 0.04, 0.06, 0.02, -0.01, 0.07]
risk_free_rate = 0.02  # 无风险利率

excess_return = statistics.mean(returns) - risk_free_rate
sharpe_ratio = excess_return / statistics.stdev(returns)
print(f'夏普比率: {sharpe_ratio:.4f}')
夏普比率: 0.3118

map():映射函数

map() 将指定函数应用于可迭代对象的每个元素

  • 语法map(function, iterable, ...)
Listing 17: map函数批量处理金融数据
# 批量将字符串价格转换为浮点数
price_strings = ['24.78', '20.15', '14.03', '22.41', '16.17']
price_floats = list(map(float, price_strings))
print(f'转换结果: {price_floats}')
转换结果: [24.78, 20.15, 14.03, 22.41, 16.17]

map() 应用:批量计算涨跌幅

Listing 18
prices_old = [100, 105, 98, 102, 110]
prices_new = [105, 110, 95, 108, 115]

# 定义涨跌幅计算函数
calc_return = lambda old, new: (new - old) / old

# map 可接受多个可迭代对象
returns = list(map(calc_return, prices_old, prices_new))
print(f'涨跌幅: {[f"{r:.2%}" for r in returns]}')
涨跌幅: ['5.00%', '4.76%', '-3.06%', '5.88%', '4.55%']

提示map() 比显式 for 循环更简洁,适合对大量数据执行统一操作。

filter():过滤函数

filter() 根据指定函数的条件筛选元素

  • 语法filter(function, iterable)
Listing 19: filter函数筛选符合条件的股票
all_returns = [0.05, -0.02, 0.03, -0.01, 0.04, -0.03, 0.06]

# 筛选正收益
positive_returns = list(filter(lambda x: x > 0, all_returns))
print(f'正收益: {[f"{r:.2%}" for r in positive_returns]}')

# 筛选高收益(>3%)
high_returns = list(filter(lambda x: x > 0.03, all_returns))
print(f'高收益: {[f"{r:.2%}" for r in high_returns]}')
正收益: ['5.00%', '3.00%', '4.00%', '6.00%']
高收益: ['5.00%', '4.00%', '6.00%']

filter() 应用:多条件筛选

Listing 20
stocks = [
    {'name': 'A', 'return': 0.05, 'risk': 0.10},
    {'name': 'B', 'return': 0.08, 'risk': 0.15},
    {'name': 'C', 'return': 0.06, 'risk': 0.08}
]

# 筛选条件: 收益 > 5% 且 风险 < 10%
filtered = list(filter(
    lambda s: s['return'] > 0.05 and s['risk'] < 0.10,
    stocks
))
print(f'符合条件的股票: {[s["name"] for s in filtered]}')
符合条件的股票: ['C']

zip():配对函数

zip() 将多个可迭代对象的元素逐一配对成元组。

Listing 21: zip函数组合多维度数据
names = ['中信证券', '国泰君安', '海通证券']
prices = [24.78, 20.15, 14.03]
volumes = [2500000, 1800000, 3200000]

print('股票数据:')
for name, price, volume in zip(names, prices, volumes):
    turnover = price * volume
    print(f'  {name}: 价格={price:.2f}, 成交量={volume:,}, 成交额={turnover:,.0f}')
股票数据:
  中信证券: 价格=24.78, 成交量=2,500,000, 成交额=61,950,000
  国泰君安: 价格=20.15, 成交量=1,800,000, 成交额=36,270,000
  海通证券: 价格=14.03, 成交量=3,200,000, 成交额=44,896,000

zip() 应用:创建字典与排序

Listing 22
展开实现代码
names = ['中信证券', '国泰君安', '海通证券']
prices = [24.78, 20.15, 14.03]
volumes = [2500000, 1800000, 3200000]

# zip 快速创建字典
stock_dict = dict(zip(names, prices))
print(f'价格字典: {stock_dict}')

# 按成交量排序
print('\n按成交量排序:')
for name, price, volume in sorted(
    zip(names, prices, volumes), key=lambda x: x[2]
):
    print(f'  {name}: {volume:,}')
价格字典: {'中信证券': 24.78, '国泰君安': 20.15, '海通证券': 14.03}

按成交量排序:
  国泰君安: 1,800,000
  中信证券: 2,500,000
  海通证券: 3,200,000

综合练习:证券公司名称教学示例数据

Listing 23: 综合运用内置函数进行证券分析
companies = ['公司甲', '公司乙', '公司丙', '公司丁', '公司戊']  # 使用中性名称避免把无来源数值冒充事实
profits = [98.76, 70.70, 57.71, 51.61, 46.32]
prices = [24.78, 20.15, 14.03, 22.41, 16.17]

# 基本统计
print('=' * 50)
print('2018年净利润排名前5位证券公司分析')
print('=' * 50)
print(f'  净利润总额: {sum(profits):.2f} 亿元')
print(f'  平均净利润: {sum(profits)/len(companies):.2f} 亿元')
print(f'  最高净利润: {max(profits):.2f} 亿元')
print(f'  最低净利润: {min(profits):.2f} 亿元')
==================================================
2018年净利润排名前5位证券公司分析
==================================================
  净利润总额: 325.10 亿元
  平均净利润: 65.02 亿元
  最高净利润: 98.76 亿元
  最低净利润: 46.32 亿元

综合练习:排名与计算方法检查

Listing 24
展开实现代码
companies = ['公司甲', '公司乙', '公司丙', '公司丁', '公司戊']
profits = [98.76, 70.70, 57.71, 51.61, 46.32]
prices = [24.78, 20.15, 14.03, 22.41, 16.17]

# 净利润排名(降序)
print('【净利润排名】')
for rank, (company, profit) in enumerate(
    sorted(zip(companies, profits), key=lambda x: x[1], reverse=True), 1
):
    print(f'  {rank}. {company}: {profit:.2f} 亿元')

# 计算方法检查:公司净利润(亿元)不能直接除以每股价格
print('\n【停止】缺少股本、每股收益与同日价格,不能计算可解释估值指标')
【净利润排名】
  1. 公司甲: 98.76 亿元
  2. 公司乙: 70.70 亿元
  3. 公司丙: 57.71 亿元
  4. 公司丁: 51.61 亿元
  5. 公司戊: 46.32 亿元

【停止】缺少股本、每股收益与同日价格,不能计算可解释估值指标

本章小结

函数 功能 关键用法
len() 获取长度 数据完整性检查
enumerate() 枚举索引+值 生成排名报告
sum() 求和 计算总利润/平均值
max() / min() 极值 识别最佳/最差表现
sorted() 排序 股价排序与筛选
round() 舍入 金融报表精度控制
map() / filter() 映射/过滤 批量计算与条件筛选
zip() 配对 多维数据组合

随堂练习

  • 问题 1|需要准备哪些数据?:证券代码、收益率、估值与缺失字符串列表。
  • 问题 2|需要完成哪些操作?:用 len/sorted/map/filter/zip 完成 lst-comprehensive-analysis 的配对、筛选和排名。
  • 问题 3|应得到哪些结果?:原始长度、清洗后列表、排序键与证券排名表。
  • 问题 4|怎样确认结果可靠?:核对配对长度和排序方向;长度错位或转换失败时先检查原因。
  • 问题 5|换一个情境,怎样继续应用?:把同一函数方法应用到另一组长三角公司。
  • 作答提示:请依次写清所用数据、分析过程、所得结果、核对方法和拓展思考。课程所需数据见前言中的下载入口;教学平台固定题按页面说明完成。

教师参考解答|答案与说明 1

  • 补充练习|类型转换处理缺失None 和非法字符串保持缺失,合法文本用 float() 转换,再以有效样本数核对;len/sum/min/max/sorted 只执行明确操作,不自动判断缺失机制。

教师参考解答|代码 1

展开代码(代码区可独立滚动)
raw_values=['12.5',None,'8.0','bad']  # 准备含两类缺失的估值文本
parsed_values=[float(value) if value not in (None,'bad') else None for value in raw_values]  # 转换合法值并保留缺失
valid_values=[value for value in parsed_values if value is not None]  # 构造可排名样本
print(len(valid_values),sorted(valid_values))  # 输出有效分母与升序排名

教师参考解答|答案与说明 2

  • 拓展应用答案:替换为长三角公司同一报告期估值;预期排名随缺失处理变化;用有效样本量、原始列表未变和反向排序核对,低估值不等于投资价值因果。

  • 所用数据与字段:数值列表;比较 len、sum、min、max、sorted

  • 参考代码或推导(平台保护块之外):

教师参考解答|代码 2

展开代码(代码区可独立滚动)
values=[3,1,4,2]  # 准备输入
summary=(len(values),sum(values),min(values),max(values))  # 计算摘要
print(summary,sorted(values),values)  # 同时核对新旧对象

教师参考解答|答案与说明 3

  • 参考结果:(4,10,1,4)、[1,2,3,4],原列表不变
  • 边界 / 局限:sorted 返回新对象,sort 原地修改
  • 常见错误:把 sort() 返回值当列表